package com.kyubi.common.model;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;
import java.util.Vector;

import com.kyubi.common.grammar.Tree;
import com.kyubi.common.grammar.TreeNode;

public class RuleModel implements IModel{
	public RuleModel(){
		m_RuleBigramFreq = new HashMap<String, Double>();
	}

	public void read(Vector<String> data){
		collectBigrams(data);
	}
	public Map<String, Double> getModelCounts(){
		return m_RuleBigramFreq;
	}
	
	private void collectBigrams(Vector<String> data){
		Tree syntaxTree = new Tree();
		for(int i = 0; i < data.size(); ++i){
			TreeNode node = syntaxTree.parse(data.get(i));
			UpdateRuleFreq(node);
		}
	}
	private void UpdateRuleFreq(TreeNode node){
		TreeNode outNode = null;
		String unigramRule = null;
		String bigramRule = new String();
		Queue<TreeNode> queue = new LinkedList<TreeNode>();
		queue.add(node);
		while(!queue.isEmpty()){
			outNode = queue.remove();
			if(outNode.getParent() != null){
				unigramRule = /*outNode.getParent().getHead() + "->" +*/ outNode.getHead(); 
			}
			else{
				unigramRule = outNode.getHead();
			}
			Vector<TreeNode> childNodes = outNode.getChildren();
			if(!childNodes.isEmpty()){
				for(int i = 0; i < childNodes.size(); ++i){
					//collecting the unigram rules....
					if(m_RuleBigramFreq.containsKey(unigramRule)){
						m_RuleBigramFreq.put(unigramRule, m_RuleBigramFreq.get(unigramRule) + 1);
					}
					else
					{
						m_RuleBigramFreq.put(unigramRule, new Double(1));
					}
					//collecting the bigram rules...
					bigramRule = bigramRule + childNodes.get(i).getHead();
					/*bigramRule = unigramRule + "_" + childNodes.get(i).getParent().getHead() + "->" + childNodes.get(i).getHead();
					if(m_RuleBigramFreq.containsKey(bigramRule)){
						m_RuleBigramFreq.put(bigramRule, m_RuleBigramFreq.get(bigramRule) + 1);
					}
					else{
						m_RuleBigramFreq.put(bigramRule, new Double(1));
					}*/
					queue.add(childNodes.get(i));
				}
				bigramRule = unigramRule + "_" + unigramRule + "->" + bigramRule;
				if(m_RuleBigramFreq.containsKey(bigramRule)){
					m_RuleBigramFreq.put(bigramRule, m_RuleBigramFreq.get(bigramRule) + 1);
				}
				else{
					m_RuleBigramFreq.put(bigramRule, new Double(1));
				}	
				bigramRule = "";
			}
		}
	}
	
	private Map<String, Double> m_RuleBigramFreq; //contains both rule bigrams and unigrams
}
